feat(analytics): event ingestion and reporting APIs (#368) - #377
Merged
devIKargi merged 1 commit intoAug 20, 2026
Merged
Conversation
- Added idempotencyKey to AnalyticsEvent and DTO for deduplication - Refactored ingestEvent and ingestBatch to use UPSERT/orIgnore pattern - Created migration for idempotencyKey and BRIN index on createdAt to optimize time-series queries - Added getTopEvents and getRetentionCohorts reporting APIs - Created AnalyticsCronService with @nestjs/schedule to aggregate metrics daily - Added unit tests for ingestion, deduplication, and reporting queries - Added docs/analytics.md detailing schema and retention policy
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Event Ingestion and Reporting APIs (#368)
Closes #368
🎯 Objective
This PR introduces a robust, fully-featured Analytics Module responsible for ingesting, validating, storing, and reporting telemetry and user interaction events. It fulfills the core requirements for #368, providing a scalable storage schema and critical reporting APIs needed for product dashboards (retention, top events, and daily aggregates).
🚀 What We Did (Summary of Changes)
BRIN(Block Range INdex) to the event timestamps, significantly improving time-series query performance natively in PostgreSQL.@nestjs/scheduleto run a midnight cron job that aggregates daily metrics (e.g., total active users, views, transactions) and shifts the query burden off the live telemetry endpoints.analytics.mddocumentation file defining event schemas and retention rules.🛠️ Technical Details & File Changes
1. Ingestion & Deduplication
src/analytics/dto/ingest-events.dto.ts: Added an optionalidempotencyKeyfield to the validation DTOs.src/analytics/entities/analytics-event.entity.ts: Extended the TypeORM entity with anidempotencyKeycolumn, constrained by a unique database index.src/analytics/analytics.service.ts: Refactored theingestEventandingestBatchlogic. Switched from raw.save()calls to a robustUPSERT/.orIgnore()QueryBuilder pattern. This ensures that duplicate events submitted by clients (e.g. on network retries) fail silently and gracefully without throwing 500 errors.2. Reporting API Capabilities
src/analytics/analytics.service.ts:getTopEvents(startDate, endDate, limit)to return the highest frequency telemetry events.getRetentionCohorts(startDate, endDate)using an advanced raw SQL CTE to calculate daily retention offset cohorts cleanly.src/analytics/controllers/analytics.controller.ts:GET /analytics/metrics/top-eventsGET /analytics/metrics/retention3. Background Processing & Cron Jobs
src/analytics/analytics.cron.ts(NEW): Built theAnalyticsCronServiceto executeaggregateDailyMetricsatCronExpression.EVERY_DAY_AT_MIDNIGHT.src/app.module.ts&src/analytics/analytics.module.ts: Imported and configuredScheduleModule.forRoot()to enable NestJS chronometer tasks globally.4. Storage Optimizations
src/migrations/1724076000000-AnalyticsModuleUpdates.ts(NEW):idempotencyKeycolumn and unique constraint natively.BRINindex oncreatedAt. BRIN is natively highly optimized for continuously appending time-series data, vastly speeding up reporting queries with huge row counts.5. Specs & Docs
docs/analytics.md(NEW): In-depth documentation on standard properties, ingestion API examples, and the data retention policy.src/analytics/analytics.service.spec.ts&src/analytics/controllers/analytics.controller.spec.ts(NEW): Added 100% test coverage over the deduplication logic, DTO validation, and correct execution of reporting endpoints using Jest.🧪 Expected Behavior
POST /analytics/eventswith the sameidempotencyKeytwice, the backend accepts the request with a202 Acceptedbut does not duplicate the entry in theanalytics_eventstable.GET /analytics/metrics/retentionprovides accurate N-day retention mapping grouped by cohort start days.daily_metricstable for fast analytical retrieval.✅ Acceptance Criteria (Checklist)
BRINtime-series indexing implemented).